""" Branching Fractal - Tom Fangrow, 5/13/2026 """
from tkinter import *
import math, random
root = Tk()
root.geometry('1600x1290')
root.title('Branching Fractal')
canvas = Canvas(root, width=1600, height=1200, bg='#AAAAAA', highlightthickness=0)
canvas.grid(row=0, column=0, columnspan=5)
def branching():
canvas.delete('all') # start with clean canvas
branches = []
color=''
branch = canvas.create_line(800, 1200, 800, 1200-trunk_slider.get(), width=.1*trunk_slider.get(), fill="#220800") # trunk
branches.append(branch)
for branch in branches: # ever-expanding "loop" (select one, create two more)
x1 = canvas.coords(branch)[0]
y1 = canvas.coords(branch)[1]
x2 = canvas.coords(branch)[2]
y2 = canvas.coords(branch)[3]
length = math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) # parent length
if length < 80:
color='#008000' # green
else:
color='#220800' # brown
if length < 10: # stop branching when branches are too short (otherwise it branches forever)
break
w = .08*length # w = width of line (branch)
e = 2*random_slider.get() # e = arbitrary degree of randomness
ratio = branch_slider.get()/100 # branch length as a fraction of trunk length
a = math.atan2(y1-y2, x2-x1) # parent angle in radians (+y is down)
b = .01*random.randint(-e, e)+angle_slider.get()*math.pi/360 # child half-angle in radians
c = random.randint(-e, e)+length*ratio # child length
branch = canvas.create_line(x2, y2, x2+c*math.cos(a+b), y2-c*math.sin(a+b), fill=color, width=w) # left child
branches.append(branch)
branch = canvas.create_line(x2, y2, x2+c*math.cos(a-b), y2-c*math.sin(a-b), fill=color, width=w) # right child
branches.append(branch)
canvas.update()
start_button = Button(root, text=' DRAW FRACTAL ', command=branching)
start_button.grid(row=2, column=4, pady=10)
trunk_slider = Scale(root, from_=60, to=600, length=250, orient=HORIZONTAL)
trunk_slider.grid(row=2, column=0)
trunk_slider.set(350)
trunk_label = Label(root, text='trunk length (pixels)')
trunk_label.grid(row=3, column=0)
branch_slider = Scale(root, from_=20, to=100, length=250, orient=HORIZONTAL)
branch_slider.grid(row=2, column=1)
branch_slider.set(70)
branch_label = Label(root, text='branch length (% of trunk length)')
branch_label.grid(row=3, column=1)
angle_slider = Scale(root, from_=5, to=180, length=250, orient=HORIZONTAL)
angle_slider.grid(row=2, column=2)
angle_slider.set(50)
angle_label = Label(root, text='branch angle (degrees)')
angle_label.grid(row=3, column=2)
random_slider = Scale(root, from_=0, to=11, length=100, orient=HORIZONTAL)
random_slider.grid(row=2, column=3)
random_slider.set(3)
random_label = Label(root, text='randomness')
random_label.grid(row=3, column=3)
root.mainloop()
Back to Tom Fangrow's Home Page